package client.logic.chat;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.security.PrivateKey;

import packets.Packet;

import client.gui.frmChatFrame;
import client.logic.GuiFacade;
import encription.SecurityHandler;

/**
 * class to receive chat messages from another client
 */
public class ChatReciever extends Thread{
	private Socket _sock;
	private frmChatFrame _chatFrame;
	private PrivateKey _key;
	private BufferedInputStream _in;

	/**
	 * creates an instance of ChatReciever
	 * @param sock the socket which the chat receiver communicates with
	 * @param c the GUI frame of which this instance send messages to
	 * @param key the public key to decrypt the received messages with
	 */
	public ChatReciever(Socket sock , frmChatFrame c, PrivateKey key){
		_chatFrame = c;
		_sock = sock;
		_key = key;
	}

	/**
	 * actions to perform when running the ChatReciever thread
	 * waits for chat messages and prints them to the screen
	 */
	public void run(){
		try{
			
			_in = new BufferedInputStream(_sock.getInputStream());			//open input stream to receive messages
			byte [] encryptText = new byte[2048];							//buffer for receiving messages
			while(!_sock.isClosed() && !_sock.isInputShutdown() && !_sock.isOutputShutdown() && _sock.isConnected()){ 
				//attempts receives a message as long as the channel is open
				int bytes = _in.read(encryptText); 							//receive the message into the buffer
				if  (bytes!=0){
					Packet Pac = ((Packet)(SecurityHandler.getObject(SecurityHandler.decrypt(encryptText, _key, bytes))));		//decrypt the message and get the packet
					String message = Pac.getStringContent();				//retrieve the message from the packet
					if (message!=null){
						GuiFacade.getInstance().recieveMessage(_chatFrame, message); 	//show the message to the screen
					} else {
						break;
					}
				}
			}
			_in.close();

			System.out.println("Connection closed by other client");
			GuiFacade.getInstance().closeChatWindow(_chatFrame);
		} catch (SocketException e){
			//connection closed by client
		} catch (Exception e){
			SecurityHandler.catchException("recieving chat messages", e, true);
			//e.printStackTrace();
		}
	}

	/**
	 * closes the chat receiver
	 */
	public void close() {
		try {
			_in.close();
		} catch (IOException e) {
			SecurityHandler.catchException("closing chat", e, true);
			//e.printStackTrace();
		}
	}
}
